From 281d3b20f0bb012d977274fd087de4b0378f581c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 4 Aug 2005 13:13:02 +0000 Subject: [PATCH] Fix iopl() syscall so that we pass LTP's iopl02 test. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c | 6 +----- linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c | 2 +- linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c | 2 +- linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c | 3 ++- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c | 7 +------ linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c | 2 +- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c | 2 +- 7 files changed, 8 insertions(+), 16 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c index 3aa6c5a4cf..314033ce41 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ioport.c @@ -113,16 +113,12 @@ asmlinkage long sys_iopl(unsigned int new_io_pl) if ((new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO)) return -EPERM; - /* Maintain OS privileges even if user attempts to relinquish them. */ - if (new_io_pl == 0) - new_io_pl = 1; - /* Change our version of the privilege levels. */ current->thread.io_pl = new_io_pl; /* Force the change at ring 0. */ op.cmd = PHYSDEVOP_SET_IOPL; - op.u.set_iopl.iopl = new_io_pl; + op.u.set_iopl.iopl = (new_io_pl == 0) ? 1 : new_io_pl; HYPERVISOR_physdev_op(&op); return 0; diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c index 6cc2be6450..76e5d04801 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c @@ -539,7 +539,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas if (unlikely(prev->io_pl != next->io_pl)) { iopl_op.cmd = PHYSDEVOP_SET_IOPL; - iopl_op.u.set_iopl.iopl = next->io_pl; + iopl_op.u.set_iopl.iopl = (next->io_pl == 0) ? 1 : next->io_pl; mcl->op = __HYPERVISOR_physdev_op; mcl->args[0] = (unsigned long)&iopl_op; mcl++; diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c index 50e0cf52e1..93b9745386 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c @@ -1636,7 +1636,7 @@ void __init setup_arch(char **cmdline_p) efi_map_memmap(); op.cmd = PHYSDEVOP_SET_IOPL; - op.u.set_iopl.iopl = current->thread.io_pl = 1; + op.u.set_iopl.iopl = 1; HYPERVISOR_physdev_op(&op); #ifdef CONFIG_ACPI_BOOT diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index 1b3d1c7e6f..e75b424aa8 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -880,7 +880,8 @@ static int __init do_boot_cpu(int apicid) ctxt.user_regs.cs = __KERNEL_CS; ctxt.user_regs.eip = start_eip; ctxt.user_regs.esp = idle->thread.esp; - ctxt.user_regs.eflags = (1<<9) | (1<<2) | (idle->thread.io_pl<<12); +#define X86_EFLAGS_IOPL_RING1 0x1000 + ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1; /* FPU is set up to default initial state. */ memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt)); diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c index 7d7385cf61..08ccd0f79d 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/ioport.c @@ -30,7 +30,6 @@ asmlinkage long sys_iopl(unsigned int new_io_pl, struct pt_regs *regs) unsigned int old_io_pl = current->thread.io_pl; physdev_op_t op; - if (new_io_pl > 3) return -EINVAL; @@ -38,16 +37,12 @@ asmlinkage long sys_iopl(unsigned int new_io_pl, struct pt_regs *regs) if ((new_io_pl > old_io_pl) && !capable(CAP_SYS_RAWIO)) return -EPERM; - /* Maintain OS privileges even if user attempts to relinquish them. */ - if (new_io_pl == 0) - new_io_pl = 1; - /* Change our version of the privilege levels. */ current->thread.io_pl = new_io_pl; /* Force the change at ring 0. */ op.cmd = PHYSDEVOP_SET_IOPL; - op.u.set_iopl.iopl = new_io_pl; + op.u.set_iopl.iopl = (new_io_pl == 0) ? 1 : new_io_pl; HYPERVISOR_physdev_op(&op); return 0; diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c index a6b1a843cf..f19ff9b94b 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/process.c @@ -465,7 +465,7 @@ struct task_struct *__switch_to(struct task_struct *prev_p, struct task_struct * if (unlikely(prev->io_pl != next->io_pl)) { iopl_op.cmd = PHYSDEVOP_SET_IOPL; - iopl_op.u.set_iopl.iopl = next->io_pl; + iopl_op.u.set_iopl.iopl = (next->io_pl == 0) ? 1 : next->io_pl; mcl->op = __HYPERVISOR_physdev_op; mcl->args[0] = (unsigned long)&iopl_op; mcl++; diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c index 080121e1ab..0a5a202651 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c @@ -824,7 +824,7 @@ void __init setup_arch(char **cmdline_p) #endif op.cmd = PHYSDEVOP_SET_IOPL; - op.u.set_iopl.iopl = current->thread.io_pl = 1; + op.u.set_iopl.iopl = 1; HYPERVISOR_physdev_op(&op); if (xen_start_info.flags & SIF_INITDOMAIN) { -- 2.30.2